package com.atguigu.core.util;

import com.atguigu.core.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;

/**
 * 异常信息工具类
 *
 * @author Navi
 */
@Slf4j
public class ExceptionUtil {
  public static final int REDO_OK_FLAG = 500;
  public static final int REDO_NG_FLAG = 600;

  private static final String EXCEPTION_LINE_INFO = "Exception Thread[ID : {} Name : {}] - Message : {}";
  private static final String EXCEPTION_LINE_CLASS = "Exception Class[{} Method : {} Line : {}]";
  private static final String EXCEPTION_LINE = "Exception {}]";
  private static final String NAVI_PACKAGE_NAME = "com.navi";

  private static final String CHECK_INFO_REG = ".*\\{\\}.*";

  /**
   * 异常信息 {} 替换
   *
   * @param exceptionInfo
   * @param params
   * @return
   */
  public static String procExceptionInfo(String exceptionInfo, String... params) {
    return MessageParseUtils.replaceTemplateMessage(exceptionInfo, params);
  }

  public static void logExceptionInfo(Exception ex) {
    long threadId = Thread.currentThread().getId();
    String threadName = Thread.currentThread().getName();
    log.error(EXCEPTION_LINE_INFO, threadId, threadName, ExceptionUtils.getMessage(ex) + " - " + ExceptionUtils.getRootCauseMessage(ex));
    String[] exceptionList = ExceptionUtils.getRootCauseStackTrace(ex);
    for (int i = 0; i < exceptionList.length; i++) {
      if (i > 10) {
        break;
      }
      String exceptionStr = exceptionList[i];
      log.error(EXCEPTION_LINE, exceptionStr);
    }
  }

  public static String getExceptionInfo(Throwable ex) {
    StringBuilder exceptionInfoString = new StringBuilder();
    exceptionInfoString.append(ExceptionUtils.getMessage(ex)).append(" - ").append(ExceptionUtils.getRootCauseMessage(ex));
    String[] exceptionList = ExceptionUtils.getRootCauseStackTrace(ex);
    int sourceErrorCount = 0;
    for (int i = 0; i < exceptionList.length; i++) {
      if (sourceErrorCount > 5) {
        break;
      }
      String exceptionStr = exceptionList[i];
      if (exceptionStr.contains(NAVI_PACKAGE_NAME)) {
        sourceErrorCount++;
      }
      exceptionInfoString.append(exceptionStr);
    }
    return exceptionInfoString.toString();
  }

  public static String getExceptionMessage(Throwable ex) {
    return ExceptionUtils.getMessage(ex);
  }

  /**
   * 业务异常识别
   *
   * @param logFormat
   * @param exceptionMethod
   * @param executeTime
   * @param ex
   */
  public static void exceptionLog(String logFormat, String exceptionMethod, Long executeTime, Throwable ex) {
    if (ex instanceof BizException || ex.getCause() instanceof BizException) {
      log.warn(logFormat, exceptionMethod, executeTime, ExceptionUtil.getExceptionMessage(ex));
    } else {
      log.error(logFormat, exceptionMethod, executeTime, ExceptionUtil.getExceptionInfo(ex));
    }
  }

  /**
   * 业务异常识别
   *
   * @param logFormat
   * @param exceptionMethod
   * @param executeTime
   * @param ex
   */
  public static void exceptionLog(String logFormat, String exceptionMethod, Long executeTime, String params, Throwable ex) {
    if (ex instanceof BizException || ex.getCause() instanceof BizException) {
      log.warn(logFormat, exceptionMethod, executeTime, params, ExceptionUtil.getExceptionMessage(ex));
    } else {
      log.error(logFormat, exceptionMethod, executeTime, params, ExceptionUtil.getExceptionInfo(ex));
    }
  }

  /**
   * 业务异常识别
   *
   * @param ex
   */
  public static String exceptionLog(Throwable ex) {
    if (ex instanceof BizException || ex.getCause() instanceof BizException) {
      return ExceptionUtil.getExceptionMessage(ex);
    } else {
      return ExceptionUtil.getExceptionInfo(ex);
    }
  }
}
